package ZJX_net

import (
	"TCP-sever/interface"
	"TCP-sever/utils"
	"fmt"
)

/*
	消息处理模块
*/

type MsgHandler struct {
	//存放每个MsgId对应的方法
	Apis map[uint32]ZJX_interface.IRouter
	//消息队列，使用带缓冲的chan实现
	TaskQueue []chan ZJX_interface.IRequest
	//最大的Worker池数量
	WorkerPoolSize uint32
	//当前池子号
	WorkerId uint32
}

func NewMsgHandler() ZJX_interface.IMsgHandler {
	handler := &MsgHandler{
		Apis:           make(map[uint32]ZJX_interface.IRouter),
		WorkerPoolSize: utils.GlobalObject.WorkerPoolSize,
		TaskQueue:      make([]chan ZJX_interface.IRequest, utils.GlobalObject.WorkerPoolSize),
		WorkerId:       uint32(0),
	}
	return handler
}

/**
执行业务代码
*/
func (m *MsgHandler) DoMsgHandler(request ZJX_interface.IRequest) {
	router, ok := m.Apis[request.GetMsgId()]
	if !ok {
		fmt.Println("api MsgId =", request.GetMsgId(), "is NOT POUND! You need register!")
		return
	}

	fmt.Println("Ready to do router , MsgId =", request.GetMsgId())
	router.PreHandle(request)
	router.Handler(request)
	router.PostHandle(request)
}

func (m *MsgHandler) AddRouter(msgId uint32, router ZJX_interface.IRouter) {
	//1 判断当前Id是否已绑定方法
	if _, ok := m.Apis[msgId]; ok {
		return
	}

	//2 添加方法\
	m.Apis[msgId] = router
}

func (m *MsgHandler) StartWorkerPool() {
	for i := uint32(0); i < utils.GlobalObject.WorkerPoolSize; i++ {
		//给queue分配空间
		m.TaskQueue[i] = make(chan ZJX_interface.IRequest, utils.GlobalObject.MaxWorkerTaskLen)

		//开启当前Worker
		go m.startOneWorker(int(i), m.TaskQueue[i])
	}
}

func (m *MsgHandler) SendMsgTaskQueue(request ZJX_interface.IRequest) {

	m.TaskQueue[m.WorkerId] <- request
	fmt.Println("from url:", request.GetConnection().GetRemoteAddr(), "WorkerId =", m.WorkerId)
	m.WorkerId = (m.WorkerId + 1) % utils.GlobalObject.WorkerPoolSize
}

func (m *MsgHandler) startOneWorker(workerId int, que chan ZJX_interface.IRequest) {
	fmt.Println("Worker start id =", workerId)

	for {
		select {
		case request := <-que:
			//如果当前管道有消息传来，则执行方法处理消息
			m.DoMsgHandler(request)
		}
	}
}
